home *** CD-ROM | disk | FTP | other *** search
- // General Fraction class - also handles Mixed Numbers & Decimals
-
-
- // M\Cooper
- // 3425 Chestnut Ridge Rd.
- // Grantsville, MD 21536-9801
- // --------------------------
- // Email: thegrendel@aol.com
-
-
- #include <iostream.h>
- #include <stdlib.h>
- #include <string.h>
-
- #define MAXLEN 30
- #define ARGCOUNT 4
- #define OPERATOR_ERROR 5
- #define WRONG_NO_OF_ARGS 2
- #define MAXIMUM(x,y) (x>=y) ? x:y
- #define SLASH '/'
- #define DASH '-'
- #define TERM1 argv[1]
- #define OP *argv[2]
- #define TERM2 argv[3]
- #define POSITIVE 0
- #define NEGATIVE 1
-
- const long SCALING_FACTOR = 1000;
-
- enum boolean {FALSE, TRUE};
-
- void input_error();
-
- class Fraction
- {
- protected:
- long numerator;
- long denominator;
- double decimal_equivalent;
-
- long integer_part;
- long part_numerator;
- long part_denominator;
-
- public:
- Fraction()
- { numerator = 0; denominator = 1;
- part_numerator = 0; part_denominator = 1;
- decimal_equivalent = 0.; integer_part = 0;}
-
- Fraction( long num, long denom )
- {
- numerator = num;
- denominator = denom;
- decimal_equivalent = (double)numerator/(double)denominator;
- part_numerator = 0; part_denominator = 1;
- integer_part = 0;
- }
- Fraction( double decimal )
- {
- numerator = (long) (SCALING_FACTOR * decimal);
- denominator = SCALING_FACTOR;
- decimal_equivalent = decimal;
- part_numerator = 0; part_denominator = 1;
- integer_part = 0;
- }
-
-
- void show()
- {
- cout << "The result: "
- << numerator << SLASH << denominator << endl;
-
- if( integer_part )
- {
- cout << "Converted to a mixed number: " << integer_part;
- if( part_numerator )
- cout << "-" << part_numerator << SLASH << part_denominator
- << endl;
- }
- cout << "Decimal equivalent = " << decimal_equivalent << endl;
- }
-
- Fraction operator + (Fraction fr) // addition
- {
- long num, denom;
-
- if( denominator == fr.denominator )
- {
- num = numerator + fr.numerator;
- denom = denominator;
- }
- else
- {
- num = numerator * fr.denominator
- + fr.numerator * denominator;
- denom = denominator * fr.denominator;
- }
-
- return ( Fraction(num,denom) );
- }
-
- Fraction operator - (Fraction fr) // subtraction
- {
- long num, denom;
-
- if( denominator == fr.denominator )
- {
- num = numerator - fr.numerator;
- denom = denominator;
- }
- else
- {
- num = numerator * fr.denominator
- - fr.numerator * denominator;
- denom = denominator * fr.denominator;
- }
-
- return ( Fraction(num,denom) );
- }
-
- Fraction operator * (Fraction fr) // multiplication
- {
- long num = numerator * fr.numerator;
- long denom = denominator * fr.denominator;
-
- return ( Fraction(num,denom) );
- }
-
- Fraction operator / (Fraction fr) // division
- {
- long num = numerator * fr.denominator;
- long denom = denominator * fr.numerator;
-
- return ( Fraction(num,denom) );
- }
-
- Fraction parse( char * );
- boolean isfactor( long, long );
- long gcf( long, long );
- void reduce();
- void improper_to_proper();
- void proper_to_improper();
-
- };
-
- boolean Fraction::isfactor( long number, long factor )
- {
- if( !(number % factor) )
- return (TRUE);
- else
- return (FALSE);
- }
-
- long Fraction::gcf( long num, long denom )
- {
- long smaller,
- larger,
- temp;
-
- larger = MAXIMUM(num,denom);
- smaller = temp = (num==larger) ? denom : num;
-
- while( temp )
- if( isfactor( smaller, temp ) && isfactor( larger, temp ) )
- break;
- else
- temp--;
-
- return (temp);
- }
-
- void Fraction::reduce()
- {
- long temp;
- int sign = POSITIVE;
-
- if( numerator < 0) //negative fraction
- { sign = NEGATIVE; numerator *= -1; }
-
- while( (temp = gcf( numerator, denominator ) ) >1 )
- { numerator /= temp; denominator /= temp; }
-
- if( sign )
- numerator *= -1; //change back to negative
-
- return;
- }
-
-
- void Fraction::improper_to_proper()
- {
- if( labs(numerator) >= denominator )
- {
- integer_part = numerator / denominator;
- part_numerator = labs( numerator - denominator * integer_part) ;
- part_denominator = denominator;
- }
- else
- {
- integer_part = 0;
- part_numerator = numerator;
- part_denominator = denominator;
- }
- }
-
- void Fraction::proper_to_improper()
- { numerator = numerator + integer_part*denominator; }
-
- Fraction Fraction::parse( char *token )
- {
- char *denom_ptr,
- *dash_ptr;
- Fraction temp;
-
- if ( (dash_ptr = strchr( ++token, DASH )) != NULL )
- // skip 1st char., in case minus sign...
- {
- temp.integer_part = atol( --token ); // renormalize
- token = ++dash_ptr;
- }
- else --token; // renormalize
-
- if( (denom_ptr = strchr( token, SLASH )) != NULL )
- {
- temp.numerator = atol( token );
- temp.denominator = atol( ++denom_ptr );
- temp.proper_to_improper();
- temp.decimal_equivalent =
- (double)temp.numerator/(double)temp.denominator;
- }
- else
- temp = atof( token );
-
- return (temp);
- }
-
- Fraction operation_on( Fraction& t1, Fraction& t2, char oper )
- {
- Fraction temp;
-
- switch (oper)
- {
- case '+':
- temp = t1 + t2;
- break;
- case '-':
- temp = t1 - t2;
- break;
- case '*':
- temp = t1 * t2;
- break;
- case '/':
- temp = t1 / t2;
- break;
- default:
- input_error();
- exit( OPERATOR_ERROR );
- }
-
- return (temp) ;
- }
-
-
-
- void main( int argc, char* argv[] )
- {
-
- Fraction term1,
- term2,
- result;
-
- if( argc != ARGCOUNT )
- input_error();
-
- term1 = term1.parse( TERM1 );
- term2 = term2.parse( TERM2 );
- result = operation_on( term1, term2, OP );
-
- result.reduce();
- result.improper_to_proper();
- result.show();
-
- }
-
- void input_error()
- {
- cout << endl
- << "Format: fraction aaa/bbb <operator> ccc/ddd" << endl
- << " or" << endl
- << " AAA-aaa/bbb <operator> CCC-ccc/ddd" << endl;
-
- exit( WRONG_NO_OF_ARGS );
- }
-